import { Component, Input, Output, EventEmitter, ViewChild, AfterViewInit, OnInit, OnChanges, SimpleChanges } from '@angular/core';
import { ApplicationService } from "../../../service/application.service";
function _windowWrapper() {
  return window;
}

@Component({
  selector: 'app-audio',
  templateUrl: './audio.component.html',
  styleUrls: ['./audio.component.css']
})
export class AudioComponent implements AfterViewInit, OnInit, OnChanges {

  private window: any = _windowWrapper();
  private timeout: any;
  private startTransition: any;
  private interval: any;
  private list: string;
  /**
   * 播放按钮是否可见
   * 默认false
   * @type {boolean}
   * @memberof AudioComponent
   */
  @Input() playButton: boolean = false;
  /**
   * 暂停按钮是否可见
   * 默认false
   * @type {boolean}
   * @memberof AudioComponent
   */
  @Input() pauseButton: boolean = false;
  /**
   * 上一首下一首按钮是否可见
   * 默认false
   * @type {boolean}
   * @memberof AudioComponent
   */
  @Input() selectableButton: boolean = false;
  /**
   * 菜单按钮是否可见
   * 默认false
   * @type {boolean}
   * @memberof AudioComponent
   */
  @Input() muteButton: boolean = false;
  /**
   * 资源路径
   * 
   * @type {Array<string>}
   * @memberof AudioComponent
   */
  @Input() src: string;

  /**
   * 是否可以控制播放器
   * 默认false
   * @type {boolean}
   * @memberof AudioComponent
   */
  @Input() controls: boolean = false;

  /**
   * 是否自动播放
   * 默认false
   * @type {boolean}
   * @memberof AudioComponent
   */
  @Input() autoplayautoplay: boolean = false;
  /**
   * 是否循环播放
   * 默认false
   * @type {boolean}
   * @memberof AudioComponent
   */
  @Input() loop: boolean = false;
  /**
   * 音量
   * 默认1，最大Max
   * 
   * @type {number}
   * @memberof AudioComponent
   */
  @Input() volume: number = 1;
  /**
   * 设置从playlist中设置开始播放的索引
   * 默认0
   * @type {number}
   * @memberof AudioComponent
   */
  @Input() startPosition: number = 0;

  /** Number in s, in order to start the transition, default: 5s */
  @Input() transition: number = 5;
  /** Interval in order to set the audio transition, in ms, default: 500ms. */
  @Input() intervalTransition = 500;
  /** Define if transition, default: false. */
  @Input() transitionEnd: boolean = true;
  /** Define the preload status, default metadata. */
  @Input() transitionStart: boolean = false;


  /**
   * 预载资源信息
   * 默认'metadata'
   * none:不预载
   * metadata:预载资源信息 
   * auto:自动   * 
   * @type {string}
   * @memberof AudioComponent
   */
  @Input() preload: string = 'metadata';
  /** Define the mute status, default false. */

  /**
   * 是否静音
   * 默认false
   * 
   * @type {boolean}
   * @memberof AudioComponent
   */
  @Input() muted: boolean = false;



  /**
   * 播放列表
   * 对外输出播放列表
   * @type {EventEmitter}
   */
  @Output() playlist = new EventEmitter();

  /**
   * 当前播放信息
   * 对外输出当前播放信息
   * @memberof AudioComponent
   */
  @Output() current = new EventEmitter();

  /**
   * 当前进度信息
   * 对外输出当前进度
   * @memberof AudioComponent
   */
  @Output() progress = new EventEmitter();

  /**
   * 下载信息
   * 对外输出当前曲目下载信息
   * @memberof AudioComponent
   */
  @Output() downloading = new EventEmitter();


  /**
   * 
   * 
   * @memberof AudioComponent
   */
  @ViewChild('audioplayer') player;
  /**
   * 
   * 
   * @type {string}
   * @memberof AudioComponent
   */
  public baseUrl: string;

  constructor(
    private application: ApplicationService
  ) {

  }
  ngOnChanges(changes: SimpleChanges) {
    if (changes['src'] && changes['src'].currentValue) {
      if (!changes['src'].firstChange) {
        this.baseUrl = this.baseUrl + this.src;
      }
    }
  }
  ngOnInit() {
    this.baseUrl = this.application.appConfigData.appRestful.split("/webapi")[0];
    this.baseUrl += '/img/';
    this.baseUrl = this.baseUrl + this.src;
  }

  ngAfterViewInit() {
    if (this.transitionEnd) {
      this.player.nativeElement.addEventListener('play', () => this.audioTransition(this.player.nativeElement.duration, this.player.nativeElement.currentTime));
    }

    this.player.nativeElement.addEventListener('ended', () => {
      this.player.nativeElement.volume = this.volume;
      /** Increment array position in order to get next audio track. */
      this.startPosition += 1;
      /** If loop is true && startPosition is at last index then reset the playlist. */
      if (this.startPosition >= this.src.length && this.loop)
        this.startPosition = 0;
      /** Else stop the playlist. */
      if (this.startPosition >= this.src.length && !this.loop)
        return;
      /** Set new src track */
      this.player.nativeElement.src = this.src[this.startPosition];
      /** If onChangeTrack is set, then emit the new track. */

    });

    this.player.nativeElement.addEventListener('loadstart', () => {
      this.emitCurrentTrack();

      if (this.transitionStart)
        this.audioStartTransition(this.intervalTransition);
    });

    this.player.nativeElement.addEventListener('pause', () => {
      this.window.clearTimeout(this.timeout);
      this.window.clearInterval(this.interval);
    });

    this.player.nativeElement.addEventListener('progress', (data) => this.downloading.emit(true));
  }


  /**
   * 播放
   * 
   * @memberof AudioComponent
   */
  play(): void {
    try {
      this.player.nativeElement.play();
    }
    catch (ex) {

    }
  }
  replay(): void {
    try {
      if (this.baseUrl.startsWith(this.player.nativeElement.src)) {
        this.player.nativeElement.currentTime = 0;
      } else {
        this.player.nativeElement.src = this.baseUrl;
      }
      this.player.nativeElement.play();
    }
    catch (ex) {

    }
  }



  /**
   * 暂停
   * 
   * @memberof AudioComponent
   */
  pause(): void {
    this.player.nativeElement.pause();
  }


  /**
   * 静音
   * 
   * @memberof AudioComponent
   */
  muteVideo(): void {
    this.player.nativeElement.muted = !this.player.nativeElement.muted;
  }


  /**
   * 上一首
   * 
   * @returns 
   * @memberof AudioComponent
   */
  previousTrack() {
    /** If first track, then do nothing. */
    if (this.src.indexOf(this.player.nativeElement.src) <= 0) { return; }
    /** Else go back to previous element in track's array. */
    this.player.nativeElement.src = this.src[this.src.indexOf(this.player.nativeElement.src) - 1];
  }


  /**
   * 下一首
   * 
   * @returns {void} 
   * @memberof AudioComponent
   */
  nextTrack(): void {
    /** If last track, then do nothing. */
    if (this.src.indexOf(this.player.nativeElement.src) >= this.src.length - 1) { return; }

    /** Else, go to the next element in track's array. */
    this.player.nativeElement.src = this.src[this.src.indexOf(this.player.nativeElement.src) + 1];
  }

  /** Audio Transitions */

  /** Set transition audio. */
  audioTransition(trackDuration: number, timeElapsed: number = 0): void {
    /** Clear setInterval if defined. */
    this.window.clearInterval(this.interval);
    /** Check the currentTime elapsed, then set transition if defined. */
    this.timeout = this.setTimeoutDelay(trackDuration, timeElapsed);
  }

  audioStartTransition(interval: number): void {
    /** Start the transition. */
    this.startTransition = this.setIncrementInterval(interval);
  }


  /**
   * 设置播放时长
   * 
   * @param {number} trackDuration 
   * @param {number} timeElapsed 
   * @returns {*} 
   * @memberof AudioComponent
   */
  setTimeoutDelay(trackDuration: number, timeElapsed: number): any {
    /** Timeout who correspond to the remaining time of audio player without the transition's time ( by default 5s before the end). */
    return setTimeout(() => {
      this.interval = this.setDecrementInterval(this.intervalTransition);
    }, (trackDuration - timeElapsed) * 1000 - (this.transition * 1000));
  }


  /**
   * 设置循环次数
   * 
   * @param {number} interval 
   * @returns {*} 
   * @memberof AudioComponent
   */
  setIncrementInterval(interval: number): any {
    return setInterval(() => {
      /** Define the new player's volume. Increment by step of 10%.*/
      this.player.nativeElement.volume += (this.player.nativeElement.volume * 10) / 100;
      /** Security area in order to avoid error. If the player's volume is around 90%, then stop incrment, set the volume to 1. */
      if (this.player.nativeElement.volume >= 0.9) {
        this.player.nativeElement.volume = 1;
        this.window.clearInterval(this.startTransition);
      }
    }, interval);
  }

  setDecrementInterval(interval: number): any {
    return setInterval(() => {
      /** Decrement the volume by step of 10%. */
      this.player.nativeElement.volume -= (this.player.nativeElement.volume * 10) / 100;
    }, interval);
  }


  /**
   * 输出播放列表
   * 
   * @memberof AudioComponent
   */
  emitPlayList(): void {
    this.playlist.emit(this.src);
  }

  /**
   * 输出当前播放曲目
   * 
   * @memberof AudioComponent
   */
  emitCurrentTrack(): void {
    /**
     * Return an object who will contain: Url of the track, duration, textTrack, volume)
     */
    this.current.emit({
      src: this.player.nativeElement.currentSrc,
      textTracks: this.player.nativeElement.textTracks,
      volume: this.player.nativeElement.volume
    });
  }

}


// WEBPACK FOOTER //
// ./src/app/module/common/audio/audio.component.ts